﻿namespace My.Hydrator.Conventions
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
    using My.Hydrator.Formatters;
    using My.Hydrator.Helpers;

    public class BaseTypeConvention
    {
        protected readonly Random Random = new Random();

        protected Container Container
        {
            get { return SessionHelper.Container; }
        }

        protected DataTypeAttribute DataTypeAttribute { get; private set; }

        protected StringLengthAttribute StringLengthAttribute { get; private set; }

        protected RangeAttribute RangeAttribute { get; private set; }

        protected RegularExpressionAttribute RegularExpressionAttribute { get; private set; }

        protected bool IsDataTypeAttributePresent
        {
            get { return this.DataTypeAttribute != null; }
        }

        protected bool IsStringLengthAttributePresent
        {
            get { return this.StringLengthAttribute != null; }
        }

        protected bool IsRangeAttributePresent
        {
            get { return this.RangeAttribute != null; }
        }

        protected bool IsRegularExpressionAttributePresent
        {
            get { return this.RegularExpressionAttribute != null; }
        }

        protected void GetAttributes(IEnumerable<object> customAttributes)
        {
            this.DataTypeAttribute = customAttributes.OfType<DataTypeAttribute>().FirstOrDefault();
            this.StringLengthAttribute = customAttributes.OfType<StringLengthAttribute>().FirstOrDefault();
            this.RangeAttribute = customAttributes.OfType<RangeAttribute>().FirstOrDefault();
            this.RegularExpressionAttribute = customAttributes.OfType<RegularExpressionAttribute>().FirstOrDefault();
        }

        protected IDataTypeFormatter GetFormatter(DataTypeAttribute type)
        {
            return this.Container.Formatters.SingleOrDefault(x => x.FormatterDataType.DataType == type.DataType && x.FormatterDataType.CustomDataType == type.CustomDataType);
        }

        protected ITypeConvention GetConvention(Type type)
        {
            return this.Container.Conventions.SingleOrDefault(x => x.Type == type);
        }
    }
}
